package com.info.zhiduoduo.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.mapper.Condition;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.info.zhiduoduo.common.configs.CommonConfig;
import com.info.zhiduoduo.common.configs.PayConfig;
import com.info.zhiduoduo.common.configs.ZddUrlConfig;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.company.CompanyPayType;
import com.info.zhiduoduo.common.constants.maker.StudioState;
import com.info.zhiduoduo.common.constants.partner.PartnerBrokerageState;
import com.info.zhiduoduo.common.constants.partner.PartnerCrowdsourceCostState;
import com.info.zhiduoduo.common.constants.partner.PartnerStudioBrokerageType;
import com.info.zhiduoduo.common.constants.partner.RemitType;
import com.info.zhiduoduo.common.constants.pay.DaysPayOrderState;
import com.info.zhiduoduo.common.constants.pay.PayPrefix;
import com.info.zhiduoduo.common.constants.pay.ZddMerchantType;
import com.info.zhiduoduo.common.constants.pay.ZhaoShangPayOrderState;
import com.info.zhiduoduo.common.exception.Asserts;
import com.info.zhiduoduo.common.exception.RollbackException;
import com.info.zhiduoduo.common.formbean.BaseSimpleFormBean;
import com.info.zhiduoduo.common.utils.DateUtil;
import com.info.zhiduoduo.common.utils.LogUtil;
import com.info.zhiduoduo.common.utils.NumberUtil;
import com.info.zhiduoduo.common.utils.RandomUtil;
import com.info.zhiduoduo.common.utils.StringUtil;
import com.info.zhiduoduo.core.dto.dayspay.DaysAgentPayFormBean;
import com.info.zhiduoduo.core.dto.dayspay.DaysPayResDTO;
import com.info.zhiduoduo.core.dto.project.PayResultDto;
import com.info.zhiduoduo.core.dto.zhaoshang.ZhaoShangAgentPayFormBean;
import com.info.zhiduoduo.core.dto.zhaoshang.ZhaoShangOutlineDTO;
import com.info.zhiduoduo.core.dto.zhaoshang.ZhaoShangPayResDTO;
import com.info.zhiduoduo.core.dto.zhaoshang.ZhaoShangTransactionOutlineFormBean;
import com.info.zhiduoduo.core.formbean.ListPartnerStudioWithdrawsFromBean;
import com.info.zhiduoduo.core.service.CoreBrokerageService;
import com.info.zhiduoduo.core.service.CorePartnerService;
import com.info.zhiduoduo.core.service.WxMessageService;
import com.info.zhiduoduo.core.service.WxPartnerMessageService;
import com.info.zhiduoduo.core.service.common.BaseService;
import com.info.zhiduoduo.repository.dto.partner.PartnerMonthlyCostDto;
import com.info.zhiduoduo.repository.dto.partner.PartnerStudioWithdrawDto;
import com.info.zhiduoduo.repository.entity.maker.MakerStudio;
import com.info.zhiduoduo.repository.entity.partner.PartnerAccount;
import com.info.zhiduoduo.repository.entity.partner.PartnerAccountflow;
import com.info.zhiduoduo.repository.entity.partner.PartnerBankcard;
import com.info.zhiduoduo.repository.entity.partner.PartnerBrokerage;
import com.info.zhiduoduo.repository.entity.partner.PartnerMonthlyCrowdCost;
import com.info.zhiduoduo.repository.entity.partner.PartnerStudioWithdraw;
import com.info.zhiduoduo.repository.entity.partner.PartnerWithdraw;
import com.info.zhiduoduo.repository.mapper.partner.PartnerBankcardMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerBrokerageMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerMonthlyCrowdCostMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerStudioWithdrawMapper;
import com.info.zhiduoduo.repository.mapper.partner.PartnerWithdrawMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.validation.Valid;

@Service
@Transactional(rollbackFor = RollbackException.class)
public class CorePartnerServiceImpl extends BaseService implements CorePartnerService {

	@Autowired
	WxPartnerMessageService wxPartnerMessageService;
	@Autowired
	WxMessageService wxMessageService;
	@Autowired
	CoreBrokerageService coreBrokerageService;

	@Autowired
	PartnerBankcardMapper partnerBankcardMapper;
	@Autowired
	PartnerBrokerageMapper partnerBrokerageMapper;
	@Autowired
	PartnerWithdrawMapper partnerWithdrawMapper;
	@Autowired
	PartnerStudioWithdrawMapper partnerStudioWithdrawMapper;
	@Autowired
	PartnerMonthlyCrowdCostMapper partnerMonthlyCrowdCostMapper;

	@Autowired
	ZddUrlConfig zddUrlConfig;
	@Autowired
	PayConfig payConfig;
	@Autowired
	CommonConfig commonConfig;

	public SmartResult handleWithdrawInternal(int wdid, int partnerid) {
		PartnerAccount account = new PartnerAccount().selectOne(Condition.create().eq("partnerid", partnerid));
		Asserts.notNull(account);

		if (account.getRemitType() == RemitType.ONLINE) {
			Asserts.notAnyEmpty(StatusMsg.StatusMsg_451, account.getWechatNumber(), account.getEmail());
			return handleOnlineWithdraw(wdid, account);
		} else if (account.getRemitType() == RemitType.OFFLINE) {
			return handleStudioWithdraw(account);
		}
		return SmartResult.fail(StatusMsg.StatusMsg_101);
	}

	public SmartResult<PartnerStudioWithdrawDto> listPartnerStudioWithdraws(
			BaseSimpleFormBean<ListPartnerStudioWithdrawsFromBean> formBean) {
		@Valid ListPartnerStudioWithdrawsFromBean reqdata = formBean.getReqdata();
		String name = reqdata.getName();
		int state = reqdata.getState();
		Date from = reqdata.getFrom();
		Date to = reqdata.getTo();

		Page<PartnerStudioWithdrawDto> page = PageHelper.startPage(formBean.getPage(), formBean.getRows());
		partnerStudioWithdrawMapper.list(name, state, from, to);

		return SmartResult.ofPage(page);
	}

	/**
	 * 处理提现结果
	 *
	 * @param withdraw
	 */
	public void handleWithdrawState(PartnerWithdraw withdraw, String orderState, String responseCode, String responseMsg) {
		if (withdraw == null) return;
		withdraw.setErrorcode(responseCode).setErrormsg(responseMsg);

		switch (orderState) {
			case "CREATE":
				withdraw.setState(Constants.TRADE_CREATE);
				break;
			case "IN_PROCESS":
				withdraw.setState(Constants.TRADE_IN_PROCESS);
				break;
			case "SUCCESS":
				withdraw.setState(Constants.TRADE_SUCCESS).setFinishtime(new Date());
				doAfterWithdrawSuccess(withdraw);
				break;
			case "FAIL":
				withdraw.setState(Constants.TRADE_FAIL).setFinishtime(new Date());
				wxMessageService.notifyPartnerWithdrawFail(withdraw);
				break;
			case "REFUSE":
				withdraw.setState(Constants.TRADE_REFUSE).setFinishtime(new Date());
				wxMessageService.notifyPartnerWithdrawFail(withdraw);
				break;
			default:
				break;
		}
		withdraw.updateById();
	}

	private SmartResult handleStudioWithdraw(PartnerAccount account) {

		// 判断是否已经绑定了工作室
		if (NumberUtil.safeInt(account.getStudioId()) <= 0) {
			return SmartResult.fail(StatusMsg.StatusMsg_519);
		}
		MakerStudio studio = new MakerStudio().selectById(account.getStudioId());
		if (studio == null || studio.getState() != StudioState.CONFIRMED) {
			return SmartResult.fail(StatusMsg.StatusMsg_520);
		}

		Integer partnerid = account.getPartnerid();
		boolean exceed = false;

		// ******************* 统计所有的 佣金 *****************
		List<PartnerBrokerage> candidateBrokerageList;
		BigDecimal candidateBrokerage = BigDecimal.ZERO;
		List<PartnerBrokerage> allBrokerageList = partnerBrokerageMapper.getNormalBrokerageListByPartnerIdAndState(partnerid,
				PartnerBrokerageState.SETTLED);
		candidateBrokerageList = Lists.newArrayList();
		// 以默认的id排序的, 先创建的佣金记录先被提现
		for (PartnerBrokerage brokerage : allBrokerageList) {
			BigDecimal currTotalBrokerage = candidateBrokerage.add(brokerage.getBrokerage());
			// 单笔提现不能超过5万, 超过后的下次提现
			if (currTotalBrokerage.doubleValue() >= commonConfig.getPartnerWithdrawQuota()) {
				exceed = true;
				break;
			}
			// 当前提现在限额内,添加到可提现的列表中
			candidateBrokerage = currTotalBrokerage;
			candidateBrokerageList.add(brokerage);
		}

		PartnerStudioWithdraw withdraw = null;
		if (candidateBrokerage.doubleValue() > 0) {
			withdraw = new PartnerStudioWithdraw().setPartnerid(partnerid)
					.setBrokerageType(PartnerStudioBrokerageType.ZHIDUODUO)
					.setAmount(candidateBrokerage)
					.setStarttime(new Date());
			withdraw.insert();
			// 更新状态
			List<Integer> ids = candidateBrokerageList.stream().map(PartnerBrokerage::getBrokerageid).collect(Collectors.toList());
			new PartnerBrokerage().setState(PartnerBrokerageState.WITHDRAWING)
					.setWdid(withdraw.getId())
					.setRemitType(RemitType.OFFLINE)
					.update(Condition.create().in("brokerageid", ids));
		}

		// ******************* 统计所有的智众包佣金 *****************
		// 可提现的众包佣金列表，包含众包项目佣金+众包成本佣金
		PartnerStudioWithdraw crowdsourceWithdraw = null;
		List<PartnerBrokerage> crowdsourceBrokerageList = partnerBrokerageMapper.getCrowdsourceBrokerageListByPartnerIdAndState(partnerid,
				PartnerBrokerageState.SETTLED);
		List<PartnerMonthlyCostDto> partnerMonthlyCostList = partnerMonthlyCrowdCostMapper.listMonthlyCost(partnerid,
				PartnerCrowdsourceCostState.UNSETTLED);

		// 可提现的众包佣金合计
		BigDecimal candidateCrowdsourceBrokerage = BigDecimal.ZERO;
		// 可提现的佣金列表
		List<PartnerBrokerage> candidateCrowdsourceBrokerageList = new ArrayList<>();
		List<PartnerMonthlyCostDto> candidatePartnerCostList = new ArrayList<>();
		for (PartnerBrokerage partnerBrokerage : crowdsourceBrokerageList) {
			BigDecimal currTotalBrokerage = candidateCrowdsourceBrokerage.add(partnerBrokerage.getBrokerage());
			// 单笔提现不能超过5万, 超过后的下次提现
			if (currTotalBrokerage.doubleValue() >= commonConfig.getPartnerWithdrawQuota()) {
				exceed = true;
				break;
			}
			// 当前提现在限额内,添加到可提现的列表中
			candidateCrowdsourceBrokerage = currTotalBrokerage;
			candidateCrowdsourceBrokerageList.add(partnerBrokerage);
		}
		for (PartnerMonthlyCostDto partnerMonthlyCost : partnerMonthlyCostList) {
			BigDecimal currTotalBrokerage = candidateCrowdsourceBrokerage.add(partnerMonthlyCost.getTotalProfit());
			// 单笔提现不能超过5万, 超过后的下次提现
			if (currTotalBrokerage.doubleValue() >= commonConfig.getPartnerWithdrawQuota()) {
				exceed = true;
				break;
			}
			// 当前提现在限额内,添加到可提现的列表中
			candidateCrowdsourceBrokerage = currTotalBrokerage;
			candidatePartnerCostList.add(partnerMonthlyCost);
		}
		// 创建合伙人工作室的智众包提现记录
		if (candidateCrowdsourceBrokerage.doubleValue() > 0) {
			crowdsourceWithdraw = new PartnerStudioWithdraw().setPartnerid(partnerid)
					.setBrokerageType(PartnerStudioBrokerageType.CROWDSOURCE)
					.setAmount(candidateCrowdsourceBrokerage)
					.setStarttime(new Date());
			crowdsourceWithdraw.insert();
			// 更新状态
			for (PartnerBrokerage partnerBrokerage : candidateCrowdsourceBrokerageList) {
				partnerBrokerage.setWdid(crowdsourceWithdraw.getId()).setState(PartnerBrokerageState.WITHDRAWING).updateById();
			}
			for (PartnerMonthlyCostDto partnerMonthlyCost : candidatePartnerCostList) {
				new PartnerMonthlyCrowdCost().setId(partnerMonthlyCost.getId())
						.setState(PartnerCrowdsourceCostState.WITHDRAWING)
						.setWdid(crowdsourceWithdraw.getId())
						.updateById();
			}
		}

		//  和智众包都没有可提佣金
		if (candidateBrokerage.equals(BigDecimal.ZERO) && candidateCrowdsourceBrokerage.equals(BigDecimal.ZERO))
			return smartResult(StatusMsg.StatusMsg_502);

		// 发送消息给胡总,提示
		wxMessageService.sendPartnerStudioWithdrawNotice(account, withdraw, crowdsourceWithdraw);

		return exceed ? SmartResult.success(candidateBrokerage.add(candidateCrowdsourceBrokerage)) : SmartResult.success();
	}

	private SmartResult handleOnlineWithdraw(int wdid, PartnerAccount account) {
		int partnerid = account.getPartnerid();
		boolean repay = wdid > 0;
		/*PartnerWithdraw partnerWithdraw = partnerWithdrawMapper.getTodayDataByPartnerId(partnerid);
		if(null != partnerWithdraw){
			//已经有提现交易记录，判断是否是重新支付
			if (repay) {
				partnerWithdraw.setRepay(1).updateById();
			} else {
				return returnValue(StateMsg.StatusMsg_514);
			}
		}*/

		PartnerBankcard validCard = partnerBankcardMapper.getValidCard(partnerid);
		Asserts.notNull(validCard, StatusMsg.StatusMsg_206);

		// 是否超过单次提现限额
		boolean exceed = false;
		// 可提现的佣金列表
		List<PartnerBrokerage> candidateBbrokerageList;
		if (repay) {
			//重新提现
			candidateBbrokerageList = partnerBrokerageMapper.getBrokerageListByWdid(wdid);
		} else {
			// 提交新的提现, 判断佣金是否可以自提, 机构合伙人或提现方式为线下的方式 不能自提
			Asserts.notTrue(NumberUtil.equals(account.getPartnerType(), Constants.PARTNER_ACCOUNT_TYPE_ORGAN) ||
					NumberUtil.equals(account.getRemitType(), RemitType.OFFLINE), StatusMsg.StatusMsg_518);

			List<PartnerBrokerage> allBrokerageList = partnerBrokerageMapper.getNormalBrokerageListByPartnerIdAndState(partnerid,
					PartnerBrokerageState.SETTLED);
			BigDecimal tempBrokerage = BigDecimal.ZERO;
			candidateBbrokerageList = Lists.newArrayList();
			// 以默认的id排序的, 先创建的佣金记录先被提现
			for (PartnerBrokerage brokerage : allBrokerageList) {
				BigDecimal currTotalBrokerage = tempBrokerage.add(brokerage.getBrokerage());
				// 单笔提现不能超过5万, 超过后的下次提现
				if (currTotalBrokerage.doubleValue() >= commonConfig.getPartnerWithdrawQuota()) {
					exceed = true;
					break;
				}
				// 当前提现在限额内,添加到可提现的列表中
				tempBrokerage = currTotalBrokerage;
				candidateBbrokerageList.add(brokerage);
			}
		}

		// 总可提现的佣金金额
		BigDecimal candidateBrokerage = candidateBbrokerageList.stream()
				.map(PartnerBrokerage::getBrokerage)
				.filter(Objects::nonNull)
				.reduce(BigDecimal::add)
				.orElse(BigDecimal.ZERO);

		Asserts.isTrue(candidateBrokerage.compareTo(BigDecimal.ZERO) > 0, StatusMsg.StatusMsg_502);
		Asserts.isTrue(candidateBrokerage.doubleValue() >= 100, StatusMsg.StatusMsg_512);

		//提现需要2元的手续费。直接从总佣金中扣除。
		candidateBrokerage = candidateBrokerage.subtract(BigDecimal.valueOf(2));

		//提现记录
		PartnerWithdraw withdraw = new PartnerWithdraw().setWdno(RandomUtil.createRandomNo(PayPrefix.PWD, ""))
				.setPartnerid(partnerid)
				.setAmount(candidateBrokerage)
				.setAcctname(validCard.getPayername())
				.setAcctno(validCard.getAcctno())
				.setBankname(validCard.getBankname())
				.setPurpose("合伙人" + account.getRealname() + "佣金提现")
				.setCreatetime(new Date());

		if (withdraw.insert()) {
			//将提现id设置到每个佣金记录中,并且佣金状态变为提现中
			candidateBbrokerageList.forEach(bro -> bro.setWdid(withdraw.getWdid())
					.setState(PartnerBrokerageState.WITHDRAWING)
					.setRemitType(RemitType.ONLINE)
					.updateById());

			if (doCallZhaoShangPayApi(withdraw)) {
				return exceed ? SmartResult.success(candidateBrokerage) : SmartResult.success(candidateBrokerage);
			}
		}
		return smartResult(StatusMsg.StatusMsg_445);
	}

	/**
	 * 调用开联通支付接口，提现
	 *
	 * @param withdraw
	 * @return
	 */
	private boolean doCallKltPayApi(PartnerWithdraw withdraw) {
		RestTemplate rest = new RestTemplate();
		BaseSimpleFormBean<PartnerWithdraw> payFormBean = new BaseSimpleFormBean<>();
		payFormBean.setReqdata(withdraw);

		String url = zddUrlConfig.getBasePayUrl() + payConfig.getSingleWithdrawUrl();
		LogUtil.info("提现请求调用 url = " + url);
		SmartResult smartResult = rest.postForObject(url, payFormBean, SmartResult.class);

		if (smartResult.getObject() == null || smartResult.getState() != StatusMsg.StatusMsg_100.getState()) {
			//支付失败,回滚并显示失败原因
			if (smartResult.getObject() != null) {
				PayResultDto payResult = JSON.parseObject(JSON.toJSONString(smartResult.getObject()), PayResultDto.class);
				smartResult.setMsg(payResult.getResponseMsg());
				throw new RollbackException(payResult.getResponseMsg());
			}
			throw new RollbackException(smartResult.getMsg());
			/*try {
				throw new RuntimeException("支付失败,回滚并显示失败原因");
			} catch (Exception e) {
				LogUtil.info(e.getMessage());
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}*/

			// return returnValue;

		} else {
			//支付接口调用成功,查看交易结果
			PayResultDto payResult = JSON.parseObject(JSON.toJSONString(smartResult.getObject()), PayResultDto.class);
			withdraw.setRequestid(payResult.getRequestId());
			handleWithdrawState(withdraw, payResult.getOrderState(), payResult.getResponseCode(), payResult.getResponseMsg());
			//更新交易结果
			return true;
		}
	}

	/**
	 * 调用支付接口，提现
	 *
	 * @param withdraw
	 * @return
	 */
	private boolean doCallDaysPayApi(PartnerWithdraw withdraw) {
		RestTemplate rest = new RestTemplate();
		DaysAgentPayFormBean formBean = DaysAgentPayFormBean.of(withdraw, CompanyPayType.DAYS_JIUGE);
		String url = zddUrlConfig.getBasePayUrl() + payConfig.getDaysAgentPayUrl();
		LogUtil.info("提现请求调用 url = " + url);
		SmartResult smartResult = rest.postForObject(url, formBean, SmartResult.class);
		return handleDaysPayResult(withdraw, smartResult);
	}

	private boolean handleDaysPayResult(PartnerWithdraw withdraw, SmartResult smartResult) {
		if (smartResult.getObject() == null || smartResult.isFailed()) {
			//支付失败,回滚并显示失败原因
			String rollbackMsg = "";
			if (smartResult.getObject() != null) {
				DaysPayResDTO payResult = JSON.parseObject(JSON.toJSONString(smartResult.getObject()), DaysPayResDTO.class);
				rollbackMsg = payResult.getResponseRemark();
			} else {
				rollbackMsg = smartResult.getMsg();
			}

			LogUtil.info("支付失败,回滚并显示失败原因");
			throw new RollbackException(rollbackMsg);

		} else {
			//支付接口调用成功,查看交易结果
			DaysPayResDTO payResult = JSON.parseObject(JSON.toJSONString(smartResult.getObject()), DaysPayResDTO.class);
			withdraw.setPartnerOrderNo(payResult.getOrderNo()).setRequestid(payResult.getSequenceNo());
			return handleDaysWithdrawTradeState(withdraw, payResult.getOrderState(), payResult.getResponseCode(),
					payResult.getResponseRemark());
		}

	}

	public boolean handleDaysWithdrawTradeState(PartnerWithdraw withdraw, String orderState, String responseCode, String responseMark) {
		Asserts.notNull(withdraw, StatusMsg.PAYMENT_NOT_EXISTS_ERROR);
		switch (orderState) {
			case DaysPayOrderState.NOT_PAY:
				withdraw.setState(Constants.TRADE_CREATE);
				break;
			case DaysPayOrderState.HANDLING:
			case DaysPayOrderState.PRIMARY_VERIFIED:
			case DaysPayOrderState.SECONDARY_VERIFIED:
			case DaysPayOrderState.PAYING:
				withdraw.setState(Constants.TRADE_IN_PROCESS);
				break;
			case DaysPayOrderState.PAY_SUCCESSFUL:
				withdraw.setState(Constants.TRADE_SUCCESS).setFinishtime(new Date());
				doAfterWithdrawSuccess(withdraw);
				break;
			case DaysPayOrderState.PAY_FAILED:
				withdraw.setState(Constants.TRADE_FAIL).setFinishtime(new Date());
				//合伙人提现失败通知指定操作人员
				wxMessageService.notifyPartnerWithdrawFail(withdraw);
				break;
			case "":
			default:
				withdraw.setState(Constants.TRADE_FAIL).setFinishtime(new Date());
				break;
		}
		withdraw.setErrorcode(responseCode).setErrormsg(responseMark);
		return withdraw.updateById();
	}

	public boolean handleZhaoShangsWithdrawTradeState(PartnerWithdraw withdraw, String orderState, String responseCode,
	                                                  String responseMark) {
		Asserts.notNull(withdraw, StatusMsg.PAYMENT_NOT_EXISTS_ERROR);
		if (ZhaoShangPayOrderState.SUCCESS.equals(orderState)) {
			withdraw.setState(Constants.TRADE_SUCCESS).setFinishtime(new Date());
			doAfterWithdrawSuccess(withdraw);
		} else if (ZhaoShangPayOrderState.FAIL.equals(orderState)) {
			withdraw.setState(Constants.TRADE_FAIL).setFinishtime(new Date());
			//合伙人提现失败通知指定操作人员
			wxMessageService.notifyPartnerWithdrawFail(withdraw);
		} else {
			//判断交易时间是否过了10分钟,如果超过了10分钟查询交易概要
			long differTime = DateUtil.differMinute(DateUtil.DateToStr("yyyy-MM-dd HH:mm:ss", withdraw.getCreatetime()),
					DateUtil.DateToStr("yyyy-MM-dd HH:mm:ss", new Date()));
			if (10 < differTime) {
				ZhaoShangTransactionOutlineFormBean formBean = ZhaoShangTransactionOutlineFormBean.of(
						DateUtil.DateToStr("yyyyMMdd", withdraw.getCreatetime()), withdraw.getWdno());
				//查询交易概要
				SmartResult smartResult = new RestTemplate().postForObject(
						zddUrlConfig.getBasePayUrl() + payConfig.getZhaoShangQueryOutlineUrl(), formBean, SmartResult.class);
				if (null != smartResult.getObject() && smartResult.isSuccessful()) {
					ZhaoShangOutlineDTO outline = JSON.parseObject(JSON.toJSONString(smartResult.getObject()),
							new TypeReference<ZhaoShangOutlineDTO>() {
							});
					//判断是不是支付失败
					if ("F".equals(outline.getRtnflg())) {
						withdraw.setState(Constants.TRADE_FAIL).setErrormsg(outline.getErrdsp()).setFinishtime(new Date());
						//合伙人提现失败通知指定操作人员
						wxMessageService.notifyPartnerWithdrawFail(withdraw);
					}
				}
			}
		}
		withdraw.setErrorcode(responseCode).setErrormsg(responseMark);
		return withdraw.updateById();
	}

	/**
	 * 处理提现成功后修改状态，将所有的佣金记录标记为已提现
	 *
	 * @param withdraw
	 */
	private void doAfterWithdrawSuccess(PartnerWithdraw withdraw) {
		Integer wdid = withdraw.getWdid();
		new PartnerBrokerage().setState(PartnerBrokerageState.WITHDRAWED).update(Condition.create().eq("wdid", wdid));

		//需要增加2元手续费
		BigDecimal charge = BigDecimal.valueOf(2);
		BigDecimal totalAmount = withdraw.getAmount().add(charge);

		//提现流水记录
		new PartnerAccountflow().setPartnerid(withdraw.getPartnerid())
				.setFlowtype(2)
				.setFlowAmount(totalAmount)
				.setFlowname(Constants.ACCT_FLOW_WITHDRAW)
				.setWdid(wdid)
				.insert();

		//提现手续费流水记录
		new PartnerAccountflow().setPartnerid(withdraw.getPartnerid())
				.setFlowtype(3)
				.setFlowAmount(charge)
				.setFlowname(Constants.ACCT_FLOW_SERVICE)
				.setWdid(wdid)
				.insert();

		//提现成功。通知
		wxPartnerMessageService.notifyPartnerWithdrawSucceed(withdraw);
	}

	private boolean doCallZhaoShangPayApi(PartnerWithdraw withdraw) {
		RestTemplate rest = new RestTemplate();
		ZhaoShangAgentPayFormBean formBean = ZhaoShangAgentPayFormBean.of(withdraw, ZddMerchantType.ZHAOSHANG_ZHISHENG);
		String url = zddUrlConfig.getBasePayUrl() + payConfig.getZhaoShangAgentPayUrl();
		LogUtil.info("提现请求调用 url = " + url);
		SmartResult smartResult = rest.postForObject(url, formBean, SmartResult.class);
		return handleZhaoShangPayResult(withdraw, smartResult);
	}

	private boolean handleZhaoShangPayResult(PartnerWithdraw withdraw, SmartResult smartResult) {
		if (smartResult.getObject() == null || smartResult.isFailed()) {
			//支付失败,回滚并显示失败原因
			LogUtil.info("支付失败,回滚并显示失败原因");
			throw new RollbackException(smartResult.getMsg());
		} else {
			//支付接口调用成功,查看交易结果
			ZhaoShangPayResDTO payResult = JSON.parseObject(JSON.toJSONString(smartResult.getObject()),
					new TypeReference<ZhaoShangPayResDTO>() {
					});
			if (null == payResult || StringUtil.isEmpty(payResult.getReqnbr())) {
				withdraw.setState(Constants.TRADE_FAIL).setFinishtime(new Date());
				//合伙人提现失败通知指定操作人员
				wxMessageService.notifyPartnerWithdrawFail(withdraw);
				return withdraw.updateById();
			} else {
				withdraw.setPartnerOrderNo(payResult.getReqnbr()).setState(Constants.TRADE_IN_PROCESS);
				return withdraw.updateById();
			}
		}
	}
}
